﻿//-----------------------------------------------------------------------
// <copyright file="DataPackageView.cs" company="In The Hand Ltd">
//     Copyright © 2013-14 In The Hand Ltd. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
#if !__IOS__
using Windows.Foundation;
#endif

namespace InTheHand.ApplicationModel.DataTransfer
{
    /// <summary>
    /// A read-only version of a <see cref="DataPackage"/>.
    /// Apps that receive shared content get this object when acquiring content.
    /// </summary>
    public sealed class DataPackageView
    {
        private DataPackage package;

        internal DataPackageView(DataPackage package)
        {
            this.package = package;
            this.Properties = new InTheHand.ApplicationModel.DataTransfer.DataPackagePropertySetView(package.Properties);
        }

        /// <summary>
        /// Returns the formats the <see cref="DataPackageView"/> contains.
        /// </summary>
        public IReadOnlyList<string> AvailableFormats
        {
            get
            {
                return new System.Collections.ObjectModel.ReadOnlyCollection<string>(package.data.Keys.ToArray<string>());
            }
        }

        /// <summary>
        /// Gets a <see cref="DataPackagePropertySetView"/> object, which contains a read-only set of properties for the data in the <see cref="DataPackageView"/> object.
        /// </summary>
        public InTheHand.ApplicationModel.DataTransfer.DataPackagePropertySetView Properties
        {
            get;
            private set;
        }

        /// <summary>
        /// Checks to see if the <see cref="DataPackageView"/> contains a specific data format.
        /// </summary>
        /// <param name="formatId">The name of the format.</param>
        /// <returns>True if the <see cref="DataPackageView"/> contains the format; false otherwise.</returns>
        public bool Contains(string formatId)
        {
            return AvailableFormats.Contains<string>(formatId);
        }

        private async Task<System.IO.Stream/*Windows.Storage.Streams.RandomAccessStreamReference*/> GetBitmapClr()
        {
            if (package.data.ContainsKey(StandardDataFormats.Bitmap))
            {
                object o = package.data[StandardDataFormats.Bitmap];
                if (o is System.IO.Stream)
                {
                    return o as System.IO.Stream;
                }
#if WINDOWS_PHONE
                else if (o is Microsoft.Xna.Framework.Media.Picture)
                {
                    return ((Microsoft.Xna.Framework.Media.Picture)o).GetImage();
                }
#endif
                //return (System.IO.Stream /*Windows.Storage.Streams.RandomAccessStreamReference*/)package.data[StandardDataFormats.Bitmap];
            }

            return null;
        }

#if WINDOWS_PHONE
        internal string GetBitmapFilename()
        {
            if (package.data.ContainsKey(StandardDataFormats.Bitmap))
            {
                object o = package.data[StandardDataFormats.Bitmap];
                if (o is Microsoft.Xna.Framework.Media.Picture)
                {
                    return Microsoft.Xna.Framework.Media.PhoneExtensions.MediaLibraryExtensions.GetPath((Microsoft.Xna.Framework.Media.Picture)o);
                }
            }

            return null;
        }
#endif

        /// <summary>
        /// Gets the bitmap image contained in the <see cref="DataPackageView"/>.
        /// </summary>
        /// <returns>A stream containing the bitmap image.</returns>
#if __IOS__
        public Task<System.IO.Stream> GetBitmapAsync()
        {
            return GetBitmapClr();
        }
#else
        public IAsyncOperation<System.IO.Stream/*Windows.Storage.Streams.RandomAccessStreamReference*/> GetBitmapAsync()
        {
            return GetBitmapClr().AsAsyncOperation<System.IO.Stream/*Windows.Storage.Streams.RandomAccessStreamReference*/>();
        }
#endif

        private async Task<object> GetDataClr(string formatId)
        {
            if (package.data.ContainsKey(formatId))
            {
                DataProviderHandler handler = package.data[formatId] as DataProviderHandler;

                if (handler != null)
                {
                    DataProviderRequest request = new DataProviderRequest(package, formatId);
                    handler.Invoke(request);

                }
                else
                {
                    return package.data[formatId];
                }
            }

            return null;
        }

        /// <summary>
        /// Gets the data contained in the <see cref="DataPackageView"/>.
        /// </summary>
        /// <param name="formatId">The format of the data.</param>
        /// <returns>The data.</returns>
#if __IOS__
        public Task<object> GetDataAsync(string formatId)
        {
            return GetDataClr(formatId);
        }
#else
        public IAsyncOperation<object> GetDataAsync(string formatId)
        {
            return GetDataClr(formatId).AsAsyncOperation<object>();
        }
#endif

        private async Task<string> GetTextClr()
        {
            if (package.data.ContainsKey(StandardDataFormats.Text))
            {
                DataProviderHandler handler = package.data[StandardDataFormats.Text] as DataProviderHandler;

                if(handler != null)
                {
                    DataProviderRequest request = new DataProviderRequest(package, StandardDataFormats.Text);
                    handler.Invoke(request);
                    
                }
                
                return package.data[StandardDataFormats.Text].ToString();
            }

            return null;
        }

        /// <summary>
        /// Gets the text in the <see cref="DataPackageView"/> object.
        /// </summary>
        /// <returns></returns>
#if __IOS__
        public Task<string> GetTextAsync()
        {
            return GetTextClr();

        }
#else
        public IAsyncOperation<string> GetTextAsync()
        {
            return GetTextClr().AsAsyncOperation<string>();
        }
#endif

        private async Task<Uri> GetUriClr(string format)
        {
            if (package.data.ContainsKey(format))
            {
                DataProviderHandler handler = package.data[format] as DataProviderHandler;

                if (handler != null)
                {
                    DataProviderRequest request = new DataProviderRequest(package, format);
                    handler.Invoke(request);
                }

                return (Uri)package.data[format];
            }

            return null;
        }

        /// <summary>
        /// Gets the application link in the <see cref="DataPackageView"/> object.
        /// </summary>
        /// <returns></returns>
#if __IOS__
        public Task<Uri> GetApplicationLinkAsync()
        {
            return GetUriClr(StandardDataFormats.ApplicationLink);

        }
#else
        public IAsyncOperation<Uri> GetApplicationLinkAsync()
        {
            return GetUriClr(StandardDataFormats.ApplicationLink).AsAsyncOperation<Uri>();

        }
#endif

#if !__IOS__
        /// <summary>
        /// Gets the URI in the <see cref="DataPackageView"/> object.
        /// </summary>
        /// <returns></returns>
        [Obsolete]
        public IAsyncOperation<Uri> GetUriAsync()
        {
            return GetUriClr(StandardDataFormats.Uri).AsAsyncOperation<Uri>();
        }
#endif

        /// <summary>
        /// Gets the web link in the <see cref="DataPackageView"/> object.
        /// </summary>
        /// <returns></returns>
#if __IOS__
        public Task<Uri> GetWebLinkAsync()
        {
            return GetUriClr(StandardDataFormats.WebLink);

        }
#else
        public IAsyncOperation<Uri> GetWebLinkAsync()
        {
            return GetUriClr(StandardDataFormats.WebLink).AsAsyncOperation<Uri>();
        }
#endif
    }
}
